#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <execinfo.h>

int g_sigstop = 0;
void signal_stop(int signum)
{
	if( SIGTERM == signum )//15 SIGTERM kill命令默认发送的信号，默认动作是终止信号 程序终止
	{
		printf("SIGTERM signal detected\n");
	}
	else if( SIGALRM == signum )//14 SIGALRM alarm()系统调用发送的信号 程序终止
	{
		printf("SIGALRM signal detected\n");
		g_sigstop = 1;//捕捉到stop类型的信号，执行完程序后退出
	}
}

void signal_user(int signum)
{
	if(SIGUSR1 == signum)//10 SIGUSR1  signal user1 用户自定义信号1 程序终止
	{
		printf("SIGUSR1 signal detected\n");
	}
	else if(SIGUSR2 == signum)//12 SIGUSR2  用户自定义信号2 程序终止
	{
		printf("SIGUSR2 signal detected\n");
	}
	g_sigstop = 1;
}

void signal_code(int signum)
{
	if(SIGBUS == signum)//7 SIGBUS  signal bus error 运行非本CPU相关编译器编译的程序 程序终止
	{
		printf("SIGBUS signal detected\n");
	}

	else if(SIGILL == signum)//4 SIGILL  signal illegal instruction 非法的指令 程序终止
	{
		printf("SIGILL signal detected\n");
	}
	else if(SIGSEGV == signum)//11 SIGSEGV  signal segmentation fault 段错误系统给程序发送的信号 程序终止)
	{ 
		printf("SIGSEGV signal detected\n");
	}
	exit(-1);//捕捉到code类型的信号，直接退出程序；
}

int main(int argc, char **argv)
{
	char *ptr=NULL;
	struct sigaction sigact, sigign;

      /*+--------------------------------------+
           *| Method1: Use signal() install signal |
           *+--------------------------------------+*/
          
      	signal(SIGTERM, signal_stop);
	signal(SIGALRM, signal_stop);
  	signal(SIGBUS, signal_code);
    	signal(SIGILL, signal_code);
      	signal(SIGSEGV, signal_code);
      /*+-----------------------------------------+
           *| Method2: Use sigaction() install signal |
           *+-----------------------------------------+*/
      /* Initialize the catch signal structure. */
       	sigemptyset(&sigact.sa_mask);
       	sigact.sa_flags = 0;
       	sigact.sa_handler = signal_user;
      /* Setup the ignore signal. */
       	sigemptyset(&sigign.sa_mask);
       	sigign.sa_flags = 0;
	sigign.sa_handler = SIG_IGN;
       	sigaction(SIGINT, &sigign, 0); /* ignore SIGINT signal by CTRL+C */
	sigaction(SIGUSR1, &sigact, 0); /* catch SIGUSR1 */      
	sigaction(SIGUSR2, &sigact, 0); /* catch SIGUSR1 */
     
       	printf("Program start running for 20 seconds...\n");

       	alarm(20);
      
	while( !g_sigstop )
	{
		;
	}
       	printf("Program start stop running...\n");
       	printf("Invalid pointer operator will raise SIGSEGV signal\n");
       	*ptr = 'h';    
       	return 0;
 }
